package com.cmc.cloud.cmclink.doc.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cmc.cloud.cmclink.doc.api.document.emums.CntaoEdoMsgTypeEnum;
import com.cmc.cloud.cmclink.doc.api.document.emums.DoOperationTypeEnum;
import com.cmc.cloud.cmclink.doc.api.document.emums.PartyTypeCodeEnum;
import com.cmc.cloud.cmclink.doc.api.document.emums.SendEdoPortEnum;
import com.cmc.cloud.cmclink.doc.entity.DoInfoDO;
import com.cmc.cloud.cmclink.doc.mapper.DoInfoMapper;
import com.cmc.cloud.cmclink.doc.rpcservice.EdiTransferService;
import com.cmc.cloud.cmclink.doc.service.BlnoSendEdoService;
import com.cmc.cloud.cmclink.doc.vo.blnocargovo.BlnoCargoUpdateReqVO;
import com.cmc.cloud.cmclink.doc.vo.blnocntrvo.BlnoCntrUpdateReqVO;
import com.cmc.cloud.cmclink.doc.vo.blnoscnvo.BlnoScnUpdateReqVO;
import com.cmc.cloud.cmclink.doc.vo.blnovo.BlnoBaseInfoVO;
import com.cmc.cloud.cmclink.doc.vo.blnovo.BlnoInfoVO;
import com.cmc.cloud.cmclink.doc.vo.blnovo.operatevo.BlnoOperateIdsReqVO;
import com.cmc.cloud.cmclink.doc.vo.blnovslvoyvo.BlnoVslvoyUpdateReqVO;
import com.cmc.cloud.cmclink.doc.vo.edo.CnDlcEdoBaseVO;
import com.cmc.cloud.cmclink.doc.vo.edo.CnTaoEdoBaseVO;
import com.cmc.cloud.cmclink.doc.vo.edo.CnTxgEdoBaseVO;
import com.cmc.cloud.cmclink.doc.vo.edo.EdoBaseVO;
import com.cmc.cloud.cmclink.edi.bizapi.api.edo.base.EdoBaseResult;
import com.cmc.cloud.cmclink.edi.bizapi.api.edo.cndlc.resp.CndlcEdoResponseDTO;
import com.cmc.cloud.cmclink.edi.bizapi.api.edo.cntao.resp.CntaoEdoResponseDTO;
import com.cmc.cloud.cmclink.edi.bizapi.api.edo.cntxg.resp.CntxgEdoResponseDTO;
import com.cmes.framework.common.exception.util.ServiceExceptionUtil;
import com.cmes.framework.common.util.date.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.cmc.cloud.cmclink.doc.constants.errorconstant.SendEdoErrorCodeConstants.*;


/**
 * 发送EDO
 *
 * @author heguo
 */
@Slf4j
@Service
public class BlnoSendEdoServiceImpl implements BlnoSendEdoService {

    @Resource
    private DoInfoMapper doInfoMapper;
    @Resource
    EdiTransferService ediTransferService;

    private static String MILLISECOND_FORMAT = "yyyyMMddHHmmssSSS";

    /**
     * 发送EDO
     * @param siDetailList 提单信息列表
     * @param blnoOperateIdsReqVo do操作对象
     * @param doOpType 当前do操作类型
     */
    @Override
    public void sendEdo(List<BlnoInfoVO> siDetailList, BlnoOperateIdsReqVO blnoOperateIdsReqVo, String doOpType) {
        if (CollectionUtil.isNotEmpty(siDetailList)){
            List<BlnoInfoVO> sendEdoBlNos = siDetailList.stream().filter(si -> si.getBlnoVslvoys().stream().anyMatch(v -> blnoOperateIdsReqVo.getCurrentPort().equals(v.getPodCode()))).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(sendEdoBlNos)) {
                LambdaQueryWrapper<DoInfoDO> doInfoDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                doInfoDoLambdaQueryWrapper.in(DoInfoDO::getBlnoId, sendEdoBlNos.stream().map(BlnoInfoVO::getBlnoBasInfoVO).map(BlnoBaseInfoVO::getId).collect(Collectors.toList()));
                List<DoInfoDO> doInfoDos = doInfoMapper.selectList(doInfoDoLambdaQueryWrapper);
                Map<Long, List<DoInfoDO>> doInfoDosMap = Optional.ofNullable(doInfoDos).orElse(new ArrayList<>()).stream().collect(Collectors.groupingBy(DoInfoDO::getBlnoId));
                LocalDateTime now = LocalDateTime.now();
                List<EdoBaseVO> edoBaseVos = new ArrayList<>();

                sendEdoBlNos.stream().forEach(bl -> {

                            if (SendEdoPortEnum.CNTAO.getCode().equals(blnoOperateIdsReqVo.getCurrentPort()) || SendEdoPortEnum.CNRZH.getCode().equals(blnoOperateIdsReqVo.getCurrentPort())) {
                                CnTaoEdoBaseVO cnTaoEdoVo = this.getCnTaoEdoVo(bl, blnoOperateIdsReqVo, doInfoDosMap, doOpType);
                                cnTaoEdoVo.setBlnoInfoVo(bl);
                                edoBaseVos.add(cnTaoEdoVo);
                            } else if (SendEdoPortEnum.CNDLC.getCode().equals(blnoOperateIdsReqVo.getCurrentPort())) {
                                CnDlcEdoBaseVO cnDlcEdoVo = this.getCnDlcEdoVo(bl, blnoOperateIdsReqVo, doInfoDosMap, doOpType);
                                cnDlcEdoVo.setBlnoInfoVo(bl);
                                edoBaseVos.add(cnDlcEdoVo);
                            } else if (SendEdoPortEnum.CNTXG.getCode().equals(blnoOperateIdsReqVo.getCurrentPort())) {
                                CnTxgEdoBaseVO cnTxgEdoVo = this.getCnTxgEdoVo(bl, blnoOperateIdsReqVo, doInfoDosMap, doOpType, now);
                                cnTxgEdoVo.setBlnoInfoVo(bl);
                                edoBaseVos.add(cnTxgEdoVo);
                            }
                        }
                );
                //发送EDI
                if (!CollectionUtils.isEmpty(edoBaseVos)) {
                    edoBaseVos.parallelStream().forEach(edo -> {
                        try {
                            EdoBaseResult edoBaseResult = ediTransferService.sendEdo(Collections.singletonList(edo), blnoOperateIdsReqVo.getCurrentPort(),doOpType);
                            log.info("Send edi is success.blno = {},",edo.getBlNo());
                            if (SendEdoPortEnum.CNTAO.getCode().equals(blnoOperateIdsReqVo.getCurrentPort()) || SendEdoPortEnum.CNRZH.getCode().equals(blnoOperateIdsReqVo.getCurrentPort())){
                                CntaoEdoResponseDTO cntaoEdoResponseDto = (CntaoEdoResponseDTO) edoBaseResult;
                                log.info("Edo Response :{}",cntaoEdoResponseDto.getRetDataInfo());
                            }else if (SendEdoPortEnum.CNDLC.getCode().equals(blnoOperateIdsReqVo.getCurrentPort())){
                                CndlcEdoResponseDTO cndlcEdoResponseDto = (CndlcEdoResponseDTO) edoBaseResult;
                                log.info("Edo Response :{}",cndlcEdoResponseDto.getCustomsReceipt());
                            } else if (SendEdoPortEnum.CNTXG.getCode().equals(blnoOperateIdsReqVo.getCurrentPort())){
                                CntxgEdoResponseDTO cntxgEdoResponseDTO = (CntxgEdoResponseDTO) edoBaseResult;
                                log.info("Edo Response :{}",cntxgEdoResponseDTO.getCustomsReceipt());
                            }
                        }catch (Exception e){
                            log.error("Send edi is fail.blno = {}",edo.getBlNo());
                            log.error(e.getMessage(),e);
                        }

                    });

                }
            }
        }
    }

    private void checkCnTaoEdo(CnTaoEdoBaseVO cnTaoEdoBaseVo,String doOpType){
        if (DoOperationTypeEnum.SET_DO.getCode().equals(doOpType)){
            this.checkSetDoCnTaoEdo(cnTaoEdoBaseVo);
        } else if (DoOperationTypeEnum.LOCK_DO.getCode().equals(doOpType)) {
            this.checkLockDoCnTaoEdo(cnTaoEdoBaseVo);
        } else if (DoOperationTypeEnum.CANCEL_DO.getCode().equals(doOpType)) {
            this.checkCancelDoCnTaoEdo(cnTaoEdoBaseVo);
        }

    }

    private void checkSetDoCnTaoEdo(CnTaoEdoBaseVO cnTaoEdoBaseVo) {
        if (ObjectUtils.isEmpty(cnTaoEdoBaseVo)
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getShippingAgencyCode())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getShippingAgencyName())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getVesselCode())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getVoyageNo())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getIcCard())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getBlNo())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getCertNo())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getCompanyCode())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getCompanyName())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getContactPerson())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getContactInfo())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getDeliveryCreateTime())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getSwitchOperator())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getTradeFlag())
        ){
            //CntaoEdo存在必传字段为空
            throw ServiceExceptionUtil.exception(EDO_FIELDS_IS_EMPTY);

        }

        if (ObjectUtils.isEmpty(cnTaoEdoBaseVo.getBlnoInfoVo())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getPolDesc())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getPodDesc())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getPolCode())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getPodCode())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getBlNo())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getShippingTerm())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getSpaceOwner())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getBlType())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getCntrOwner())){
            //CntxgEdo提单主体信息存在必传字段为空
            throw ServiceExceptionUtil.exception(EDO_BLNO_FIELDS_IS_EMPTY);
        }
        List<BlnoCargoUpdateReqVO> blnoCargos = cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoCargos();
        if (CollectionUtil.isEmpty(blnoCargos)){
            //货物列表为空
            throw ServiceExceptionUtil.exception(EDO_CARGO_LIST_IS_EMPTY);
        }

        boolean cargoInfoIsEmpty = blnoCargos.stream().anyMatch(cargo -> ObjectUtils.isEmpty(cargo.getCommodityEn())
                || (ObjectUtils.isEmpty(cargo.getQuantity()) || cargo.getQuantity() <= 0)
                || (ObjectUtils.isEmpty(cargo.getCargoType()))
                || ObjectUtils.isEmpty(cargo.getMarks())
                || (ObjectUtils.isEmpty(cargo.getGrossWeight()) || cargo.getGrossWeight().compareTo(BigDecimal.ZERO) < 0)
                || (ObjectUtils.isEmpty(cargo.getMeasurement()) || cargo.getMeasurement().compareTo(BigDecimal.ZERO) < 0)
        );
        if (cargoInfoIsEmpty){
            //CnTaoEdo货物信息存在必传字段为空
            throw ServiceExceptionUtil.exception(EDO_CARGO_FIELDS_IS_EMPTY);
        }
        List<BlnoCntrUpdateReqVO> blnoCntrs = cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoCntrs();
        if (CollectionUtil.isEmpty(blnoCntrs)){
            //箱信息为空
            throw ServiceExceptionUtil.exception(EDO_CNTR_LIST_IS_EMPTY);
        }
        boolean cntrInfoIsEmpty = blnoCntrs.stream().anyMatch(cntr -> ObjectUtils.isEmpty(cntr.getCntrType())
                ||ObjectUtils.isEmpty(cntr.getCntrSize())
                ||ObjectUtils.isEmpty(cntr.getLcl())
                ||ObjectUtils.isEmpty(cntr.getCntrNo())
                ||ObjectUtils.isEmpty(cntr.getSealNo())
                ||ObjectUtils.isEmpty(cntr.getQuantity())
                ||ObjectUtils.isEmpty(cntr.getGrossWeight())
                ||ObjectUtils.isEmpty(cntr.getMeasurement())
        );
        if(cntrInfoIsEmpty){
            //CndlcEdo箱信息存在必传字段为空
            throw ServiceExceptionUtil.exception(EDO_CNTR_FIELDS_IS_EMPTY);
        }
        List<BlnoScnUpdateReqVO> blnoScns = cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoScns();
        if (CollectionUtil.isEmpty(blnoCntrs)){
            //相关方为空
            throw ServiceExceptionUtil.exception(EDO_SCN_LIST_IS_EMPTY);
        }
        boolean noneMatchConsignee = blnoScns.stream().noneMatch(scn -> PartyTypeCodeEnum.CONSIGNEE.getValue().equals(scn.getPartyTypeCode()));
        boolean anyConsigneeIsEmpty = blnoScns.stream().anyMatch(scn -> PartyTypeCodeEnum.CONSIGNEE.getValue().equals(scn.getPartyTypeCode())
                && (ObjectUtils.isEmpty(scn.getCompanyAddress())));
        if (noneMatchConsignee || anyConsigneeIsEmpty){
            //不存在收货人或收货人信息存在空字段
            throw ServiceExceptionUtil.exception(EDO_SCN_CONSIGNEE_FIELDS_IS_EMPTY);
        }
    }
    private void checkLockDoCnTaoEdo(CnTaoEdoBaseVO cnTaoEdoBaseVo) {
        if (ObjectUtils.isEmpty(cnTaoEdoBaseVo)
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getShippingAgencyCode())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getShippingAgencyName())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getIcCard())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getCertNo())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getOrgRegCo())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getFunctionCode())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getMsgId())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getMsgType())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getVesselCode())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getVoyageNo())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getAcceptDepositCoCode())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getAcceptDepositCoName())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getContactInfo())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getContactAddress())
        ){
            //CntaoEdo存在必传字段为空
            throw ServiceExceptionUtil.exception(EDO_FIELDS_IS_EMPTY);
        }
        if (ObjectUtils.isEmpty(cnTaoEdoBaseVo.getBlnoInfoVo())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getSpaceOwner())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getBlType())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getBlNo())
        ) {
            //CntaoEdo提单主体信息存在必传字段为空
            throw ServiceExceptionUtil.exception(EDO_BLNO_FIELDS_IS_EMPTY);
        }
        List<BlnoCargoUpdateReqVO> blnoCargos = cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoCargos();
        if (CollectionUtil.isEmpty(blnoCargos)) {
            //货物列表为空
            throw ServiceExceptionUtil.exception(EDO_CARGO_LIST_IS_EMPTY);
        }

        boolean cargoInfoIsEmpty = blnoCargos.stream().anyMatch(cargo -> ObjectUtils.isEmpty(cargo.getCommodityEn())
                || (ObjectUtils.isEmpty(cargo.getQuantity()) || cargo.getQuantity() <= 0)
                || (ObjectUtils.isEmpty(cargo.getGrossWeight()) || cargo.getGrossWeight().compareTo(BigDecimal.ZERO) < 0)
                || (ObjectUtils.isEmpty(cargo.getMeasurement()) || cargo.getMeasurement().compareTo(BigDecimal.ZERO) < 0)
        );
        if (cargoInfoIsEmpty){
            //CndlcEdo货物信息存在必传字段为空
            throw ServiceExceptionUtil.exception(EDO_CARGO_FIELDS_IS_EMPTY);
        }
    }
    private void checkCancelDoCnTaoEdo(CnTaoEdoBaseVO cnTaoEdoBaseVo) {
        if (ObjectUtils.isEmpty(cnTaoEdoBaseVo)
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getCertNo())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getOrgRegCo())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getMsgType())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getFunctionCode())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getMsgId())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getVesselCode())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getVoyageNo())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getBlNo())
                || ObjectUtils.isEmpty(cnTaoEdoBaseVo.getReasonCode())
        ){
            //CntaoEdo存在必传字段为空
            throw ServiceExceptionUtil.exception(EDO_FIELDS_IS_EMPTY);
        }

    }
    private void checkCnDlcEdo(CnDlcEdoBaseVO cnDlcEdoBaseVo){
        if (ObjectUtils.isEmpty(cnDlcEdoBaseVo)
                || ObjectUtils.isEmpty(cnDlcEdoBaseVo.getOpType())
                || ObjectUtils.isEmpty(cnDlcEdoBaseVo.getVesselCode())
                || ObjectUtils.isEmpty(cnDlcEdoBaseVo.getVoyageNo())
                || ObjectUtils.isEmpty(cnDlcEdoBaseVo.getReqcreditCode())
                || ObjectUtils.isEmpty(cnDlcEdoBaseVo.getReqorgName())){
            //CndlcEdo存在必传字段为空
            throw ServiceExceptionUtil.exception(EDO_FIELDS_IS_EMPTY);
        }
        if (ObjectUtils.isEmpty(cnDlcEdoBaseVo.getBlnoInfoVo())
                || ObjectUtils.isEmpty(cnDlcEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO())
                || ObjectUtils.isEmpty(cnDlcEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getPolDesc())
                || ObjectUtils.isEmpty(cnDlcEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getPodDesc())
                || ObjectUtils.isEmpty(cnDlcEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getBlNo())
                || ObjectUtils.isEmpty(cnDlcEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getBlType())
                || ObjectUtils.isEmpty(cnDlcEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getShippingTerm())){
            //CndlcEdo提单主体信息存在必传字段为空
            throw ServiceExceptionUtil.exception(EDO_BLNO_FIELDS_IS_EMPTY);

        }
        List<BlnoCargoUpdateReqVO> blnoCargos = cnDlcEdoBaseVo.getBlnoInfoVo().getBlnoCargos();
        if (CollectionUtil.isEmpty(blnoCargos)){
            //货物列表为空
            throw ServiceExceptionUtil.exception(EDO_CARGO_LIST_IS_EMPTY);
        }

        boolean cargoInfoIsEmpty = blnoCargos.stream().anyMatch(cargo -> ObjectUtils.isEmpty(cargo.getCommodityEn())
                || (ObjectUtils.isEmpty(cargo.getQuantity()) || cargo.getQuantity() <= 0)
                || ObjectUtils.isEmpty(cargo.getMarks())
                || (ObjectUtils.isEmpty(cargo.getGrossWeight()) || cargo.getGrossWeight().compareTo(BigDecimal.ZERO) < 0)
                || (ObjectUtils.isEmpty(cargo.getMeasurement()) || cargo.getMeasurement().compareTo(BigDecimal.ZERO) < 0)
        );
        if (cargoInfoIsEmpty){
            //CndlcEdo货物信息存在必传字段为空
            throw ServiceExceptionUtil.exception(EDO_CARGO_FIELDS_IS_EMPTY);
        }
        List<BlnoCntrUpdateReqVO> blnoCntrs = cnDlcEdoBaseVo.getBlnoInfoVo().getBlnoCntrs();
        if (CollectionUtil.isEmpty(blnoCntrs)){
            //箱信息为空
            throw ServiceExceptionUtil.exception(EDO_CNTR_LIST_IS_EMPTY);
        }
        boolean cntrInfoIsEmpty = blnoCntrs.stream().anyMatch(cntr -> ObjectUtils.isEmpty(cntr.getCntrNo()));
        if(cntrInfoIsEmpty){
            //CndlcEdo箱信息存在必传字段为空
            throw ServiceExceptionUtil.exception(EDO_CNTR_FIELDS_IS_EMPTY);
        }
    }



    private void checkCnTxgEdo(CnTxgEdoBaseVO cnTxgEdoBaseVo){
        if (ObjectUtils.isEmpty(cnTxgEdoBaseVo)
                || ObjectUtils.isEmpty(cnTxgEdoBaseVo.getDespatcherCode())
                || ObjectUtils.isEmpty(cnTxgEdoBaseVo.getDespatcherTime())
                || ObjectUtils.isEmpty(cnTxgEdoBaseVo.getVesselCode())
                || ObjectUtils.isEmpty(cnTxgEdoBaseVo.getVoyageNo())
                || ObjectUtils.isEmpty(cnTxgEdoBaseVo.getDespatcherCode())
                || ObjectUtils.isEmpty(cnTxgEdoBaseVo.getBlNo())
                || ObjectUtils.isEmpty(cnTxgEdoBaseVo.getDoType())
                || ObjectUtils.isEmpty(cnTxgEdoBaseVo.getDoCode())
                || ObjectUtils.isEmpty(cnTxgEdoBaseVo.getDoCaptcha())){
            //CntxgEdo存在必传字段为空
            throw ServiceExceptionUtil.exception(EDO_FIELDS_IS_EMPTY);
        }

        if (ObjectUtils.isEmpty(cnTxgEdoBaseVo.getBlnoInfoVo())
                || ObjectUtils.isEmpty(cnTxgEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO())
                || ObjectUtils.isEmpty(cnTxgEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getPolDesc())
                || ObjectUtils.isEmpty(cnTxgEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getPodDesc())
                || ObjectUtils.isEmpty(cnTxgEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getBlNo())
                || ObjectUtils.isEmpty(cnTxgEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO().getCntrOwner())){
            //CntxgEdo提单主体信息存在必传字段为空
            throw ServiceExceptionUtil.exception(EDO_BLNO_FIELDS_IS_EMPTY);
        }
        List<BlnoCargoUpdateReqVO> blnoCargos = cnTxgEdoBaseVo.getBlnoInfoVo().getBlnoCargos();
        if (CollectionUtil.isEmpty(blnoCargos)){
            //货物列表为空
            throw ServiceExceptionUtil.exception(EDO_CARGO_LIST_IS_EMPTY);
        }

        boolean cargoInfoIsEmpty = blnoCargos.stream().anyMatch(cargo -> ObjectUtils.isEmpty(cargo.getCommodityEn())
                || (ObjectUtils.isEmpty(cargo.getQuantity()) || cargo.getQuantity() <= 0)
                || ObjectUtils.isEmpty(cargo.getMarks())
                || (ObjectUtils.isEmpty(cargo.getGrossWeight()) || cargo.getGrossWeight().compareTo(BigDecimal.ZERO) < 0)
                || (ObjectUtils.isEmpty(cargo.getMeasurement()) || cargo.getMeasurement().compareTo(BigDecimal.ZERO) < 0)
        );
        if (cargoInfoIsEmpty){
            //CndlcEdo货物信息存在必传字段为空
            throw ServiceExceptionUtil.exception(EDO_CARGO_FIELDS_IS_EMPTY);
        }
        List<BlnoCntrUpdateReqVO> blnoCntrs = cnTxgEdoBaseVo.getBlnoInfoVo().getBlnoCntrs();
        if (CollectionUtil.isEmpty(blnoCntrs)){
            //箱信息为空
            throw ServiceExceptionUtil.exception(EDO_CNTR_LIST_IS_EMPTY);
        }
        boolean cntrInfoIsEmpty = blnoCntrs.stream().anyMatch(cntr -> ObjectUtils.isEmpty(cntr.getCntrNo()));
        if(cntrInfoIsEmpty){
            //CndlcEdo箱信息存在必传字段为空
            throw ServiceExceptionUtil.exception(EDO_CARGO_LIST_IS_EMPTY);
        }
        List<BlnoScnUpdateReqVO> blnoScns = cnTxgEdoBaseVo.getBlnoInfoVo().getBlnoScns();
        if (CollectionUtil.isEmpty(blnoCntrs)){
            //相关方为空
            throw ServiceExceptionUtil.exception(EDO_SCN_LIST_IS_EMPTY);
        }
        boolean noneMatchConsignee = blnoScns.stream().noneMatch(scn -> PartyTypeCodeEnum.CONSIGNEE.getValue().equals(scn.getPartyTypeCode()));
        if (noneMatchConsignee){
            //不存在收货人
            throw ServiceExceptionUtil.exception(EDO_SCN_CONSIGNEE_FIELDS_IS_EMPTY);
        }


    }

    private CnTaoEdoBaseVO getCnTaoEdoVo(BlnoInfoVO bl,  BlnoOperateIdsReqVO blnoOperateIdsReqVo,Map<Long, List<DoInfoDO>> doInfoDosMap,String doOpType) {
        CnTaoEdoBaseVO cnTaoEdoBaseVo = new CnTaoEdoBaseVO();
        cnTaoEdoBaseVo.setBlnoInfoVo(bl);
        cnTaoEdoBaseVo.setBlNo(bl.getBlnoBasInfoVO().getBlNo());
        cnTaoEdoBaseVo.setPortCode(bl.getBlnoBasInfoVO().getPodCode());
        cnTaoEdoBaseVo.setEdoBatchNo(bl.getBlnoBasInfoVO().getBlNo()+LocalDateTimeUtil.format(LocalDateTime.now(), MILLISECOND_FORMAT));

        BlnoVslvoyUpdateReqVO blnoVslvoyUpdateReqVo = bl.getBlnoVslvoys().stream().filter(v -> blnoOperateIdsReqVo.getCurrentPort().equals(v.getPodCode())).findFirst().get();
        cnTaoEdoBaseVo.setVesselCode(blnoVslvoyUpdateReqVo.getVesselCode());
        cnTaoEdoBaseVo.setVoyageNo(blnoVslvoyUpdateReqVo.getVoyageIm());

        List<DoInfoDO> doInfoDo = doInfoDosMap.get(bl.getBlnoBasInfoVO().getId());
        if(CollectionUtil.isNotEmpty(doInfoDo)){
            if (!ObjectUtils.isEmpty(doInfoDo.get(0).getUniqueIdentifier())) {
                cnTaoEdoBaseVo.setCompanyCode(doInfoDo.get(0).getUniqueIdentifier());
                cnTaoEdoBaseVo.setCompanyName(doInfoDo.get(0).getDoExchangerNameCn());
            } else if (!ObjectUtils.isEmpty(doInfoDo.get(0).getReservedDoIdentifier())) {
                cnTaoEdoBaseVo.setCompanyCode(doInfoDo.get(0).getReservedDoIdentifier());
                cnTaoEdoBaseVo.setCompanyName(doInfoDo.get(0).getReservedDoNameCn());
            }
            if (DoOperationTypeEnum.SET_DO.getCode().equals(doOpType)) {
                cnTaoEdoBaseVo.setMsgType(CntaoEdoMsgTypeEnum.DELIVERY_ORDER.getCode());
                cnTaoEdoBaseVo.setFunctionCode("1");
                cnTaoEdoBaseVo.setSwitchOperator(doInfoDo.get(0).getSetDoOperator());
            } else if (DoOperationTypeEnum.CANCEL_DO.getCode().equals(doOpType)) {
                cnTaoEdoBaseVo.setMsgType(CntaoEdoMsgTypeEnum.WITHDRAW_DELIVERY_ORDER.getCode());
                cnTaoEdoBaseVo.setFunctionCode("1");
                cnTaoEdoBaseVo.setReasonCode("99");
                cnTaoEdoBaseVo.setReasonDesc("other");
            } else if (DoOperationTypeEnum.LOCK_DO.getCode().equals(doOpType)) {
                cnTaoEdoBaseVo.setMsgType(CntaoEdoMsgTypeEnum.SWITCHABLE_LIST.getCode());
                cnTaoEdoBaseVo.setFunctionCode("1");
            }
        }else {
            throw ServiceExceptionUtil.exception(DO_INFO_IS_EMPTY);
        }


        cnTaoEdoBaseVo.setFormat("json");
        cnTaoEdoBaseVo.setCompress("0");
        cnTaoEdoBaseVo.setIcCard("8950000012095");
        cnTaoEdoBaseVo.setCertNo("7d5e6cd5");
        cnTaoEdoBaseVo.setOrgRegCo("913702007062061828");
        LocalDateTime now = LocalDateTime.now();
        cnTaoEdoBaseVo.setMsgId(LocalDateTimeUtil.format(now, MILLISECOND_FORMAT));
        cnTaoEdoBaseVo.setShippingAgencyCode("913702007062061828");
        cnTaoEdoBaseVo.setShippingAgencyName("中外运集装箱运输有限公司山东分公司");
        cnTaoEdoBaseVo.setRemark("");
        cnTaoEdoBaseVo.setDeliveryOrderFileId("");
        cnTaoEdoBaseVo.setContactPerson("HANT");
        cnTaoEdoBaseVo.setContactInfo("133333333333");
        cnTaoEdoBaseVo.setContactAddress("中外运集装箱运输有限公司山东分公司");
        cnTaoEdoBaseVo.setDeliveryCreateTime(LocalDateTimeUtil.format(now, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
        cnTaoEdoBaseVo.setTradeFlag("W");
        cnTaoEdoBaseVo.setAcceptDepositCoCode("913702007062061828");
        cnTaoEdoBaseVo.setAcceptDepositCoName("中外运集装箱运输有限公司山东分公司");
        cnTaoEdoBaseVo.setEirCreateCoCode("913702007062061828");
        cnTaoEdoBaseVo.setEirCreateCoName("中外运集装箱运输有限公司山东分公司");
        cnTaoEdoBaseVo.setShippingAgencyRemark("");
        cnTaoEdoBaseVo.setDeliveryOrderNo("99999999");
        this.checkCnTaoEdo(cnTaoEdoBaseVo, doOpType);
        return cnTaoEdoBaseVo;

    }
    private CnDlcEdoBaseVO getCnDlcEdoVo(BlnoInfoVO bl,  BlnoOperateIdsReqVO blnoOperateIdsReqVo,Map<Long, List<DoInfoDO>> doInfoDosMap,String doOpType){
        CnDlcEdoBaseVO cnDlcEdoBaseVo = new CnDlcEdoBaseVO();
        cnDlcEdoBaseVo.setBlNo(bl.getBlnoBasInfoVO().getBlNo());
        cnDlcEdoBaseVo.setPortCode(bl.getBlnoBasInfoVO().getPodCode());
        cnDlcEdoBaseVo.setEdoBatchNo(bl.getBlnoBasInfoVO().getBlNo()+LocalDateTimeUtil.format(LocalDateTime.now(), MILLISECOND_FORMAT));

        if (DoOperationTypeEnum.SET_DO.getCode().equals(doOpType)){
            cnDlcEdoBaseVo.setOpType("9");
        }else if (DoOperationTypeEnum.CANCEL_DO.getCode().equals(doOpType)){
            cnDlcEdoBaseVo.setOpType("3");
        }
        List<DoInfoDO> doInfoDo = doInfoDosMap.get(bl.getBlnoBasInfoVO().getId());
        if(CollectionUtil.isNotEmpty(doInfoDo)){
            if (!ObjectUtils.isEmpty(doInfoDo.get(0).getUniqueIdentifier())){
                cnDlcEdoBaseVo.setReqcreditCode(doInfoDo.get(0).getUniqueIdentifier());
                cnDlcEdoBaseVo.setReqorgName(doInfoDo.get(0).getDoExchangerNameCn());
            } else if (!ObjectUtils.isEmpty(doInfoDo.get(0).getReservedDoIdentifier())) {
                cnDlcEdoBaseVo.setReqcreditCode(doInfoDo.get(0).getReservedDoIdentifier());
                cnDlcEdoBaseVo.setReqorgName(doInfoDo.get(0).getReservedDoNameCn());
            }
        }else {
            throw ServiceExceptionUtil.exception(DO_INFO_IS_EMPTY);
        }


        BlnoVslvoyUpdateReqVO blnoVslvoyUpdateReqVo = bl.getBlnoVslvoys().stream().filter(v -> blnoOperateIdsReqVo.getCurrentPort().equals(v.getPodCode())).findFirst().get();
        cnDlcEdoBaseVo.setVesselCode(blnoVslvoyUpdateReqVo.getVesselCode());
        cnDlcEdoBaseVo.setVoyageNo(blnoVslvoyUpdateReqVo.getVoyageIm());
        cnDlcEdoBaseVo.setBlnoInfoVo(bl);
        this.checkCnDlcEdo(cnDlcEdoBaseVo);
        return cnDlcEdoBaseVo;
    }

    private CnTxgEdoBaseVO getCnTxgEdoVo(BlnoInfoVO bl,  BlnoOperateIdsReqVO blnoOperateIdsReqVo,Map<Long, List<DoInfoDO>> doInfoDosMap,String doOpType ,LocalDateTime now){
        CnTxgEdoBaseVO cnTxgEdoBaseVo = new CnTxgEdoBaseVO();
        cnTxgEdoBaseVo.setBlNo(bl.getBlnoBasInfoVO().getBlNo());
        cnTxgEdoBaseVo.setPortCode(bl.getBlnoBasInfoVO().getPodCode());
        cnTxgEdoBaseVo.setEdoBatchNo(bl.getBlnoBasInfoVO().getBlNo()+LocalDateTimeUtil.format(LocalDateTime.now(), MILLISECOND_FORMAT));


        if (DoOperationTypeEnum.SET_DO.getCode().equals(doOpType)){
            cnTxgEdoBaseVo.setOpType("1");
        }else if (DoOperationTypeEnum.CANCEL_DO.getCode().equals(doOpType)){
            cnTxgEdoBaseVo.setOpType("2");
        }

        cnTxgEdoBaseVo.setDespatcherCode("911201167005272334");

        cnTxgEdoBaseVo.setDespatcherTime(LocalDateTimeUtil.format(now, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
        cnTxgEdoBaseVo.setConfUserName("郎涛");
        Random random = new Random();
        cnTxgEdoBaseVo.setDoCaptcha(String.format("%08d",random.nextInt(1000000)));

        List<DoInfoDO> doInfoDo = doInfoDosMap.get(bl.getBlnoBasInfoVO().getId());
        if(CollectionUtil.isNotEmpty(doInfoDo)){
            if (CollectionUtil.isNotEmpty(doInfoDo) && !ObjectUtils.isEmpty(doInfoDo.get(0).getUniqueIdentifier())){
                cnTxgEdoBaseVo.setDoCode(doInfoDo.get(0).getUniqueIdentifier());
            } else if (CollectionUtil.isNotEmpty(doInfoDo) && !ObjectUtils.isEmpty(doInfoDo.get(0).getReservedDoIdentifier())) {
                cnTxgEdoBaseVo.setDoCode(doInfoDo.get(0).getReservedDoIdentifier());
            }
            cnTxgEdoBaseVo.setDoType(doInfoDo.get(0).getDoType());
        }else {
            throw ServiceExceptionUtil.exception(DO_INFO_IS_EMPTY);
        }


        BlnoVslvoyUpdateReqVO blnoVslvoyUpdateReqVo = bl.getBlnoVslvoys().stream().filter(v -> blnoOperateIdsReqVo.getCurrentPort().equals(v.getPodCode())).findFirst().get();
        cnTxgEdoBaseVo.setVesselCode(blnoVslvoyUpdateReqVo.getVesselCode());
        cnTxgEdoBaseVo.setVoyageNo(blnoVslvoyUpdateReqVo.getVoyageIm());
        cnTxgEdoBaseVo.setBlnoInfoVo(bl);
        this.checkCnTxgEdo(cnTxgEdoBaseVo);
        return cnTxgEdoBaseVo;
    }
}
